from util import config
import random

import logging
logger = logging.getLogger('async.strategy')

# Can implement other translations here    
def to_bluetooth_target(presence):
    send_addr = presence.meta[config.get_int('async.metas', 'bluetooth-mac-key')]
    send_port = presence.meta[config.get_int('async.metas', 'bluetooth-unicast-port-key')]
    control_port = presence.meta[config.get_int('async.metas', 'control-port-key')]
    control_addr = presence.ip
    logger.debug('Bluetooth target: control addr: %s:%s ; send addr: %s:%s', 
                 control_addr, control_port, send_addr, send_port)
    return Target(presence, control_addr, control_port, send_addr, send_port)
                  
def to_wifi_target(presence):
    send_addr = presence.ip
    send_port = presence.meta[config.get_int('async.metas', 'unicast-port-key')]
    control_addr = presence.ip
    control_port = presence.meta[config.get_int('async.metas', 'control-port-key')]
    logger.debug('Wifi target: control addr: %s:%s ; send addr: %s:%s', 
                 control_addr, control_port, send_addr, send_port)
    return Target(presence, control_addr, control_port, send_addr, send_port)

class Target:
    
    def __init__(self, presence, control_addr, control_port, send_addr, send_port):
        self.presence = presence
        self.control_addr = (control_addr, control_port)
        self.send_addr = (send_addr, send_port)
    
    
class Strategy:

    def __init__(self):
        pass

    def evaluate(self, msg, neighbors):

        def not_has(neighbor):
            return not neighbor.has_at_all(msg.header.mid)
        
        possibles = filter(not_has, neighbors)
        
        logger.debug('Strategy for msg %s: Possible targets are %s', msg.header.mid, possibles)
        # Sort according to some criteria

        # ...

        targets = map(to_wifi_target, possibles)
        logger.debug('Strategy msg %s, ordered targets are %s', msg.header.mid, targets)
        network = config.get_int('async.networks', 'unicast')
        #etwork = config.get_int('async.networks', 'bluetooth-unicast')
        return (network, targets)

class RetransmissionStrategy:

    def __init__(self):
        pass

    def evaluate(self, mid, seqs, neighbors):
        
        def has(neighbor):
            return neighbor.has_complete(mid)
        possibles = filter(has, neighbors)
        
        # Randomize it a bit so that we don't 
        # continually target the same user
        random.shuffle(possibles)
        
        if possibles:
            #target = to_bluetooth_target(possibles[0])
            target = to_wifi_target(possibles[0])
        else:
            target = None
        network = config.get_int('async.networks', 'unicast')
        #network = config.get_int('async.networks', 'bluetooth-unicast')
        return (network, target)
